package org.ehe.business.overdue.service.ove;

import lombok.extern.slf4j.Slf4j;
import org.ehe.business.overdue.config.OverdueStatus;
import org.ehe.business.overdue.handler.OverdueHandler;
import org.ehe.business.overdue.service.ove.OverdueDelayService;
import org.ehe.business.overdue.util.FormatOverdueTimeUtil;
import org.ehe.business.project.domain.ProjectEntity;
import org.ehe.business.project.mapper.ProjectMapper;
import org.ehe.business.timeout.contants.BizTypeConstant;
import org.ehe.common.core.service.WorkflowService;
import org.ehe.common.sse.dto.SseMessageDto;
import org.ehe.common.sse.utils.SseMessageUtils;
import org.ehe.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 项目超期处理实现
 * @author :zhangnn
 * @className :ProjectOverdueService
 * @description: TODO
 * @date 2025-07-29 16:16:56
 */
@Service
@Slf4j
public class ProjectOverdueService  implements OverdueHandler {

    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ScheduledExecutorService scheduledExecutorService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private OverdueDelayService overdueDelayService;

    @Autowired
    private WorkflowService workflowService;

    @Override
    public String getBizType() {
        return "projectOverdue";
    }

    /**
     * 超期执行
     * @param bizId 业务ID（如方案ID、项目ID）
     */
    @Override
    public void handleOverdue(Long bizId) {
        try {
            log.info("开始处理项目超期: projectId={}", bizId);
            // 1. 更新项目状态
            ProjectEntity project = projectMapper.selectById(bizId);
            if(Objects.nonNull(project)){
                if(project.getIsOverdue().equals(OverdueStatus.PENDING)){
                    //超期未处理
                    project.setIsOverdue(OverdueStatus.OVERDUE_AND_PENDING);
                }
                projectMapper.updateById(project);
                // 2. 发送通知
                sendOverdueNotification(project);
                // 3. 再次进行超期监听延时1小时
                overdueDelayService.delay(BizTypeConstant.PROJECT+"Overdue",bizId);
            }
        } catch (Exception e) {
            log.error("处理项目超期失败: projectId={}", bizId, e);
        }
    }

    /**
     * 提前推送消息
     * @param bizId 业务ID
     */
    @Override
    public void remindBeforeOverdue(Long bizId) {
        log.info("发送项目超期提醒: projectId={}", bizId);
        overdueDelayService.remind(BizTypeConstant.PROJECT+"Overdue",bizId);
        //提醒
        ProjectEntity project = projectMapper.selectById(bizId);
        scheduledExecutorService.schedule(() -> {
            try {
                SseMessageDto dto = new SseMessageDto();
                dto.setMessage("项目【" + project.getProjectName() + "】仅剩余30分钟，请及时处理！");

                List<Long> ids = userService.queryUserIds();
                dto.setUserIds(ids);

                dto.setMessageType("REMIND");
                SseMessageUtils.publishMessage(dto);
                log.info("项目超期通知发送成功: solutionId={}", project.getId());
            } catch (Exception e) {
                log.error("发送项目超期通知失败: solutionId={}", project.getId(), e);
            }
        }, 6, TimeUnit.SECONDS);
    }

    /**
     * 发送超期通知
     */
    private void sendOverdueNotification(ProjectEntity project) {
        scheduledExecutorService.schedule(() -> {
            try {
                String overdueTime = FormatOverdueTimeUtil.formatOverdueTime(project.getIsOverdueEndTime());
                SseMessageDto dto = new SseMessageDto();
                dto.setMessage("项目【" + project.getProjectName() + "】已超期"+overdueTime+"，请及时处理！");

                List<Long> ids = userService.queryUserIds();
                dto.setUserIds(ids);

                dto.setMessageType("OVERDUE_NOTIFICATION");
                SseMessageUtils.publishMessage(dto);
                log.info("项目超期通知发送成功: solutionId={}", project.getId());
            } catch (Exception e) {
                log.error("发送项目超期通知失败: solutionId={}", project.getId(), e);
            }
        }, 5, TimeUnit.SECONDS);
    }




}
